package com.lxk.util;

import com.lxk.dao.OrdersMapper;
import com.lxk.dao.SeckillMapper;
import com.lxk.dao.SeckillOrderMapper;
import com.lxk.pojo.*;

import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 秒杀定时检查超时订单任务
 *
 * 秒杀回退：count+1, endTime设为null, ordersStatus设为4(交易关闭), seckillOrder删除
 * 增加字段：拍下时间
 *
 * @author JohnSoybean
 * @time 2020年4月1日
 */
public class SeckillOrderTimerTask extends TimerTask {

    private final static long expireMillis = 180000;    //过期时间3分钟
    private final static long expireMillisWithoutOrder = 30000;    //未生成支付订单情况下过期时间30秒

    private Timer timer;
    private Integer seckillId;

    public SeckillOrderTimerTask(Timer timer) {
        this.timer = timer;
    }

    public SeckillOrderTimerTask(Timer timer, Integer seckillId) {
        this.timer = timer;
        this.seckillId = seckillId;
    }

    @Override
    public void run() {
        try {
            SeckillMapper seckillMapper = SpringContextHolder.getBean(SeckillMapper.class);
            SeckillOrderMapper seckillOrderMapper = SpringContextHolder.getBean(SeckillOrderMapper.class);
            OrdersMapper ordersMapper = SpringContextHolder.getBean(OrdersMapper.class);
            Seckill seckill = seckillMapper.selectByPrimaryKey(seckillId);
            SeckillOrderExample example = new SeckillOrderExample();
            SeckillOrderExample.Criteria criteria = example.createCriteria();
            criteria.andSeckillIdEqualTo(seckillId);
            List<SeckillOrder> seckillOrders = seckillOrderMapper.selectByExample(example);
            Date nowTime = new Date();
            //进程何时结束：每笔预订单均生成了支付订单，且所有支付订单均已支付成功，且count==0, endtime!=null
            boolean flag = false;
            Integer count = seckill.getSeckillCount();
            Date endTime = seckill.getSeckillEndTime();
            if (count==0 && endTime!=null) {    //判断是否是否全部拍下
                flag = true;
            }
            for (SeckillOrder seckillOrder : seckillOrders) {
                Integer seckillOrderId = seckillOrder.getSeckillOrderId();
                Integer ordersId = seckillOrder.getOrdersId();
                if (ordersId!=null) {   //支付订单存在
                    Orders orders = ordersMapper.selectByPrimaryKey(ordersId);
                    Integer ordersStatus = orders.getOrdersStatus();
                    if (ordersStatus==1||ordersStatus==2||ordersStatus==3) {    //支付成功
                        //无操作
                    }else { //未支付成功
                        flag = false;
                        Date buyTime = seckillOrder.getBuyTime();
                        Date expireTime = new Date(buyTime.getTime()+expireMillis);
                        if (nowTime.after(expireTime)) {    //已超时
                            //ordersStatus设为4(交易关闭)
                            orders.setOrdersStatus(4);
                            ordersMapper.updateByPrimaryKeySelective(orders);
                            //seckillOrder删除
                            seckillOrderMapper.deleteByPrimaryKey(seckillOrderId);
                            //count+1, endTime设为null
                            seckill.setSeckillCount(seckill.getSeckillCount()+1);
                            seckill.setSeckillEndTime(null);
                            seckillMapper.updateByPrimaryKey(seckill);
                            System.out.println("#### 秒杀-超时订单检查进程：支付订单"+ordersId+"超时，已关闭 ####");
                        }
                    }
                }else { //尚未生成支付订单
                    flag = false;
                    Date buyTime = seckillOrder.getBuyTime();
                    Date expireTime = new Date(buyTime.getTime()+expireMillisWithoutOrder);
                    if (nowTime.after(expireTime)) {    //已超时
                        //seckillOrder删除
                        seckillOrderMapper.deleteByPrimaryKey(seckillOrderId);
                        //count+1, endTime设为null
                        seckill.setSeckillCount(seckill.getSeckillCount()+1);
                        seckill.setSeckillEndTime(null);
                        seckillMapper.updateByPrimaryKey(seckill);
                        System.out.println("#### 秒杀-超时订单检查进程：预订单"+ seckillOrderId +"超时，已关闭 ####");
                    }
                }
            }
            if (seckill.getIsClosed()==1) {  //若被后台设为已结束
                flag = true;
            }
            if (flag==true) {
                this.timer.cancel();
                System.out.println("#### 秒杀-超时订单检查进程：全部秒杀订单均已支付成功，任务结束 ####");
                return;
            }
        }catch(Exception e) {
        	e.printStackTrace();
        	System.out.println("#### 秒杀-超时订单检查进程：出现异常 ####");
        	this.timer.cancel();
        }
    }
}
